﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SisVenda.Business;
using SisVenda.Data;
using System.Data;
using System.Collections;
using System.Reflection;
using Froggy.Data;
using SisVenda.Web.messageBox;
using SisVenda.Web.Code;

namespace SisVenda.Web.Restrito.Fn
{
    [System.ComponentModel.DataObject(true)]
    public class CadastroProdutoFn
    {
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterProdutoID(int idProduto)
        {
            if (idProduto == 0)
                idProduto = 1;
            #region SQL
            string sql = @"SELECT *
	                            FROM Produto
	                            WHERE IdProduto = @idProduto
	                            ORDER BY Descricao";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@idProduto", DbType.Int32, idProduto);
            return db.GetDataTable();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterCnpjID(int idPessoa)
        {
            #region SQL
            string sql = @"SELECT IdPessoa, CNPJ
	                            FROM Pessoa
	                            WHERE IdPessoa = @idPessoa";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@idPessoa", DbType.Int32, idPessoa);
            return db.GetDataTable();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterComissaoProduto(int idCategoriaProduto)
        {
            #region SQL
            string sql = @"SELECT IdCategoriaProduto, Comissao
	                            FROM CategoriaProduto
	                            WHERE IdCategoriaProduto = @idCategoriaProduto";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@idCategoriaProduto", DbType.Int32, idCategoriaProduto);
            return db.GetDataTable();
        }


        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterProduto(string Descricao)
        {
            string desc = Descricao;
            Descricao = "%" + desc + "%";
            #region SQL
            string sql = @"SELECT *
	                            FROM Produto
	                            WHERE Produto.Descricao LIKE @Descricao
	                            ORDER BY Produto.Descricao";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@Descricao", DbType.String, Descricao);
            return db.GetDataTable();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterProdutoCatForID(int idProduto)
        {
            if (idProduto == 0)
                idProduto = 1;
            #region SQL
            string sql = @"SELECT produto.*, categoria.Descricao, categoria.IdCategoriaProduto, categoria.Comissao, pessoa.Nome, pessoa.CNPJ, idPessoa
                                FROM Produto produto 
                                    INNER JOIN CategoriaProduto categoria 
                                        ON produto.CategoriaProduto_IdCategoriaProduto = categoria.IdCategoriaProduto
                                    INNER JOIN ProdutoFornecedor proFor 
                                        ON produto.idProduto = proFor.Produto_IdProduto
                                    INNER JOIN Fornecedor fornecedor
                                        ON proFor.Fornecedor_Pessoa_IdPessoa = fornecedor.Pessoa_IdPessoa
                                    INNER JOIN Pessoa pessoa
                                        ON fornecedor.Pessoa_Idpessoa = pessoa.IdPessoa
                                    WHERE IdProduto = @idProduto
                                    ORDER BY produto.Descricao";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@idProduto", DbType.Int32, idProduto);
            return db.GetDataTable();
        }
        
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterProdutoCatFor(string descricao)
        {
            string desc = descricao;
            descricao = "%" + desc + "%";
            #region SQL
            string sql = @"SELECT produto.*, pessoa.nome, pessoa.CNPJ
                                FROM Produto produto 
                                    INNER JOIN CategoriaProduto categoria 
                                        ON produto.CategoriaProduto_IdCategoriaProduto = categoria.IdCategoriaProduto
                                    INNER JOIN ProdutoFornecedor proFor
                                        ON produto.idProduto = proFor.Produto_IdProduto
                                    INNER JOIN Fornecedor fornecedor
                                        ON proFor.Fornecedor_Pessoa_IdPessoa = fornecedor.Pessoa_IdPessoa
                                    INNER JOIN Pessoa pessoa
                                        ON fornecedor.Pessoa_IdPessoa = pessoa.IdPessoa
                                    WHERE produto.Descricao LIKE @descricao
	                                ORDER BY produto.Descricao";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@descricao", DbType.String, descricao);
            return db.GetDataTable();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterCategoriaProduto(string descricao)
        {
            string desc = descricao;
            descricao = "%" + desc + "%";
            #region SQL
            string sql = @"SELECT *
	                            FROM CategoriaProduto
	                            WHERE CategoriaProduto.Descricao LIKE @descricao
	                            ORDER BY CategoriaProduto.Descricao";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@descricao", DbType.String, descricao);
            return db.GetDataTable();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public DataTable ObterFornecedor(string nome)
        {
            string desc = nome;
            nome = "%" + desc + "%";
            #region SQL
            string sql = @"SELECT p.Nome, p.Cnpj, P.IdPessoa
	                            FROM Pessoa p, Fornecedor f
	                            WHERE p.IdPessoa = f.Pessoa_IdPessoa
	                            ORDER BY P.Nome";
            #endregion
            DbCommandUtil db = new DbCommandUtil(sql);
            db.AddParameter("@nome", DbType.String, nome);
            return db.GetDataTable();
        }

        public DataTable RetornarDataTable(IQueryable pObjQuery)
        {
            DataTable _dt = new DataTable();

            //Cria o DataTable
            foreach (var item in pObjQuery)
            {
                Type t = item.GetType();
                PropertyInfo[] properties = t.GetProperties();
                for (int i = 0; i < properties.Length; i++)
                {
                    _dt.Columns.Add(properties[i].Name);
                }
                break;
            }

            IEnumerator en = (IEnumerator)pObjQuery.GetEnumerator();

            //Popula o DataTable
            while (en.MoveNext())
            {
                Type ten = en.Current.GetType();
                PropertyInfo[] propertiesen = ten.GetProperties();
                DataRow _dtrow = _dt.NewRow();
                for (int i = 0; i < propertiesen.Length; i++)
                {
                    object obj = propertiesen[i].GetValue(en.Current, new object[] { });
                    _dtrow[i] = obj;
                }
                _dt.Rows.Add(_dtrow);
            }

            return _dt;
        }


        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]
        public Boolean InserirProduto(String descricao, String apelido, Decimal preco,int estoque, int estoqueMinimo, string unidade, int reserva, int categoria, int fornecedor, string codigoFabricante)
        {
            ProdutoBo produtos = new ProdutoBo();
            Produto produto = new Produto();

            produto.CategoriaProduto_IdCategoriaProduto = categoria;
            produto.Descricao = descricao;
            produto.Apelido = apelido;
            produto.Preco = preco;
            produto.EstoqueMinimo = estoqueMinimo;
            produto.Unidade = unidade;
            produto.Estoque = estoque;
            produto.CodigoFabricante = codigoFabricante;
                   
            produtos.Add(produto);

            try
            {
                produtos.SaveChanges();
                int idProduto = ObterIdProduto(descricao, preco, unidade, estoqueMinimo, codigoFabricante);
                InserirProdutoFornecedor(fornecedor, idProduto);
                MessageBox.Show("Produto incluido com sucesso!", MessageBox.MessageType.Success);
                return true;
            }
            catch
            {
                MessageBox.Show("Erro ao realizar operação!", MessageBox.MessageType.Error);
                return false;
            }               
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]
        public Boolean InserirProdutoFornecedor(int fornecedor,int idProduto)
        {
            ProdutoFornecedorBo produtosFornecedores = new ProdutoFornecedorBo();
            ProdutoFornecedor produtoFornecedor = new ProdutoFornecedor();

            produtoFornecedor.Produto_IdProduto = idProduto;
            produtoFornecedor.Fornecedor_Pessoa_IdPessoa = fornecedor;

            produtosFornecedores.Add(produtoFornecedor);

            try
            {
                produtosFornecedores.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }               

        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Update)]
        public Boolean UpdateProduto(int idProduto, string descricao, string apelido, Decimal preco, int estoqueMinimo, string unidade, int categoria, int fornecedor, string codigoFabricante)
        {
            ProdutoBo produtos = new ProdutoBo();
            Produto produto = new Produto();

            produto = produtos.Find(pro => pro.IdProduto == idProduto).First<Produto>();

            produto.CategoriaProduto_IdCategoriaProduto = categoria;
            produto.Descricao = descricao;
            produto.Apelido = apelido;
            produto.Preco = preco;
            produto.EstoqueMinimo = estoqueMinimo;
            produto.Unidade = unidade;
            produto.CodigoFabricante = codigoFabricante;

            produtos.Update(produto);

            try
            {
                produtos.SaveChanges();
                DeleteProdutoFornecedor(ObterIdFornecedorAtual(idProduto));
                InserirProdutoFornecedor(fornecedor, idProduto);
                MessageBox.Show("Produto alterado com sucesso!", MessageBox.MessageType.Success);
                return true;
            }
            catch
            {
                MessageBox.Show("Erro ao realizar operação!", MessageBox.MessageType.Error);
                return false;
            }
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]
        public Boolean DeleteProduto(int idProduto)
        {
            ProdutoBo produtos = new ProdutoBo();
            Produto produto = new Produto();

            produto = produtos.Find(pro => pro.IdProduto == idProduto).First<Produto>();

            Int32 idFornecedorCurrente = ObterIdFornecedorAtual(idProduto);
            DeleteProdutoFornecedor(idFornecedorCurrente);
            produtos.Delete(produto);
                          
            try
            {
                produtos.SaveChanges();
                MessageBox.Show("Produto deletado com sucesso!", MessageBox.MessageType.Success);
                return true;
            }
            catch
            {
                MessageBox.Show("Operação não permitida!", MessageBox.MessageType.Warning);
                InserirProdutoFornecedor(idFornecedorCurrente, idProduto);
                return false;
            }

        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]
        public Boolean DeleteProdutoFornecedor(int fornecedor)
        {
            ProdutoFornecedorBo produtosFornecedores = new ProdutoFornecedorBo();
            ProdutoFornecedor produtoFornecedor = new ProdutoFornecedor();

            produtoFornecedor = produtosFornecedores.Find(forn => forn.Fornecedor_Pessoa_IdPessoa == fornecedor).First<ProdutoFornecedor>();
            produtosFornecedores.Delete(produtoFornecedor);

            try
            {
                produtosFornecedores.SaveChanges();
                
                return true;
            }
            catch
            {
                return false;
            }
        }

        #region Obter id fornecedor e id produto
        public int ObterIdFornecedorAtual(int idProduto)
        {
            ProdutoFornecedorBo pFornecedores = new ProdutoFornecedorBo();
            ProdutoFornecedor pFornecedor = new ProdutoFornecedor();

            pFornecedor = pFornecedores.Find(pFornec => pFornec.Produto_IdProduto == idProduto).First<ProdutoFornecedor>();
            int id = pFornecedor.Fornecedor_Pessoa_IdPessoa;
            pFornecedores = null;
            pFornecedor = null;
            return id;
        }

        public int ObterIdProduto(string descricao, decimal preco, string unidade, int estoqueMinimo, string codigoFabricante)
        {
            ProdutoBo produtos = new ProdutoBo();
            Produto produto = new Produto();

            produto = produtos.Find(prod => prod.Descricao == descricao && prod.Preco == preco && prod.Unidade == unidade && prod.EstoqueMinimo == estoqueMinimo && prod.CodigoFabricante == codigoFabricante).First<Produto>();
            int id = produto.IdProduto;
            produto = null;
            produtos = null;
            return id;
        }
        #endregion
    }
}